/**
* @author Ashish Gupta
* CVSSP, University of Surrey
* Copyright (c) 2010 Ashish Gupta
* All rights reserved.
*/
/**
 * 
 */
package classification;

import image.ImageSet;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import configuration.GenePoolConfiguration;

import weka.core.Instances;

/**
 * @author Ashish
 *
 */
public class VisualCodebook implements Codebook2Classifier {
	private Double[][] codebook = null;
	private Double[] positiveHistogram = null;
	private Double[] negativeHistogram = null;
	
	public VisualCodebook(Integer numGenes, Integer numImages){
		this.positiveHistogram = new Double[numGenes];
		this.negativeHistogram = new Double[numGenes];
		this.codebook=  new Double[numImages][numGenes+1];
	}
		
	public void incrementCodebook(int row, int col){
		this.codebook[row][col]++;
	}

	/**
	 * @return the codebook
	 */
	public Double[][] getCodebook() {
		return codebook;
	}

	/* (non-Javadoc)
	 * @see classification.Codebook2Classifier#toARFFfile(java.io.File)
	 */
	@Override
	public void toARFFfile(String fileURI) throws IOException {
		File arffFile = new File(fileURI);
		FileWriter fw = new FileWriter(arffFile);
		BufferedWriter bw = new BufferedWriter(fw);
		bw.write("@RELATION visualcategory" + "\n");
		for(int i=0;i<this.codebook[i].length;i++){
			bw.write("@ATTRIBUTE " + i + " NUMERIC" + "\n");
		}
		bw.write("@ATTRIBUTE" + " class " + "{positive,negative}" + "\n");
		bw.write("@DATA" + "\n");
		for(int i=0;i<this.codebook.length;i++){
			for(int j=1;j<this.codebook[i].length;j++){//note j starts from 1 instead of 0
				bw.write(this.codebook[i][j] + ",");
			}

			if(this.codebook[i][0] == 1){
				bw.write("positive" + "\n");
			}
			else{
				bw.write("negative" + "\n");
			}
		}
		bw.close();
		fw.close();
	}

	/* (non-Javadoc)
	 * @see classification.Codebook2Classifier#toCSVfile(java.io.File)
	 */
	@Override
	public void toCSVfile(String codebookCSVFilename) throws IOException {
		File codebookCSV = new File(codebookCSVFilename);
		FileWriter fw = new FileWriter(codebookCSV);
		BufferedWriter bw = new BufferedWriter(fw);
		for(int i=0;i<this.codebook.length;i++){
			for(int j=1;j<this.codebook[i].length;j++){//note j starts from 1 instead of 0
				bw.write(this.codebook[i][j] + ",");
			}
			if(this.codebook[i][0] == 1){
				bw.write("positive" + "\n");
			}
			else{
				bw.write("negative" + "\n");
			}
		}
		bw.close();
		fw.close();
	}

	/* (non-Javadoc)
	 * @see classification.Codebook2Classifier#toFile(java.io.File)
	 */
	@Override
	public File toFile(String fileURI) {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)
	 * @see classification.Codebook2Classifier#toInstances()
	 */
	@Override
	public Instances toInstances() {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * @param positiveHistogram the positiveHistogram to set
	 */
	public void calcPositiveHistogram(GenePoolConfiguration geneConfig) {
//		this.positiveHistogram = new Double[geneConfig.getNumGenes()];
//		Iterator<ArrayList<Double>> itr = this.visualCodebook.iterator();
//		while(itr.hasNext()){
//			ArrayList<Double> histogram = itr.next();
//			if(histogram.get(0) == 1){ // category symbol literal to be changed to category symbol
//				for(int i = 1; i < histogram.size(); i++){
//					this.positiveHistogram[i-1]+=histogram.get(i);
//				}
//			}
//		}
		for(int i =0;i<this.codebook.length;i++){
			if(this.codebook[i][0]==1){
				for(int j=1;j<this.codebook[i].length;j++){
					this.positiveHistogram[i-1]+=this.codebook[i][j];
				}
			}
		}
	}

	

	/**
	 * @param negativeHistogram the negativeHistogram to set
	 */
	public void calcNegativeHistogram(GenePoolConfiguration geneConfig) {
//		this.negativeHistogram = new Double[geneConfig.getNumGenes()];
//		Iterator<ArrayList<Double>> itr = this.visualCodebook.iterator();
//		while(itr.hasNext()){
//			ArrayList<Double> histogram = itr.next();
//			if(histogram.get(0) == -1){
//				for(int i=1;i<histogram.size();i++){
//					this.negativeHistogram[i-1]+=histogram.get(i);
//				}
//			}
//		}
		for(int i =0;i<this.codebook.length;i++){
			if(this.codebook[i][0]==-1){
				for(int j=1;j<this.codebook[i].length;j++){
					this.negativeHistogram[i-1]+=this.codebook[i][j];
				}
			}
		}
	}

	/**
	 * @param positiveHistogram the positiveHistogram to set
	 */
	public void setPositiveHistogram(Double[] positiveHistogram) {
		this.positiveHistogram = positiveHistogram;
	}

	/**
	 * @return the positiveHistogram
	 */
	public Double[] getPositiveHistogram() {
		return positiveHistogram;
	}

	/**
	 * @param negativeHistogram the negativeHistogram to set
	 */
	public void setNegativeHistogram(Double[] negativeHistogram) {
		this.negativeHistogram = negativeHistogram;
	}

	/**
	 * @return the negativeHistogram
	 */
	public Double[] getNegativeHistogram() {
		return negativeHistogram;
	}
	
	/**
	 * @param codebook the codebook to set
	 */
	public void setCodebook(ImageSet imageSet, GenePoolConfiguration geneConfig) {
		for(int i=0;i<imageSet.getImageList().getClassLabels().size();i++){
			this.codebook[i][0] = imageSet.getImageList().getClassLabels().get(i);
			for(int j = 0; j < geneConfig.getNumGenes();j++){
				this.codebook[i][j+1] = imageSet.getImages().get(i).getHistogram().get(j);
			}
		}
	}

	
	
	

}
